//
// Created by Victor on 2019/10/22.
//

#include <stdio.h>

void initArrayTemp();

void assignment();

void mutiAssignment();

void pointerInfo();

int sumArray();
void resetArrayToZero();

void changeNumberByPointer(int *);
void changeNumber(int a);

int main() {

//    initArrayTemp();
//    assignment();
//    mutiAssignment();
//    pointerInfo();


    int a[5] = {1, 2, 3, 4, 5};
    printf("total = %d\n", sumArray(a, 5));

    int b[5] = {2, 3, 4, 5, 1};
    printf("\noriginal array to zero:\n");
    for (int i = 0; i < 5; ++i) {
        printf("%d ", b[i]);
    }
    resetArrayToZero(b, 5);
    for (int i = 0; i < 5; ++i) {
        printf("%d ", b[i]);
    }

    printf("\n修改值：\n");
    int number = 4;
    changeNumber(number);
    printf("changeNumber(int a) -> %d\n", number);
    changeNumberByPointer(&number);
    printf("changeNumberByPointer(int * a) -> %d\n", number);

    return 0;
}

void changeNumberByPointer(int * a){
    *a = (*a) * (*a);
}

void changeNumber(int a){
    a = a * a;
}

// 这个方法的参数是数组的首元素地址, 也可以使用 int a[] 代替更能明确声明的是一个数组形参
int sumArray(int *a, int arraySize){
    int total = 0;
    int i = 0;
    for (i = 0; i < arraySize ; ++i) {
        total += a[i]; // a[i] == *(a + i)
    }
    return total;
}


void resetArrayToZero(int a[], int arraySize){
    printf("\nreset array to zero:\n");
    for (int i = 0; i < arraySize; ++i) {
        a[i] = 0;   // 相当与直接修改地址对应的值，即原始数据的内容会被修改
    }
}


void pointerInfo() {
    int a[10] = {1, 3, 4};  // a 是数组a的首元素地址 &a[0]

    printf("%p\n", a); // 通常以十六进制 %p 来表示元素指针的值

    int *addrA = a;
    printf("%p\n", addrA);

    printf("a + 1 = %p\n", a + 1);
    printf("a + 2 = %p\n", a + 2);

    printf("%p = %p\n", (a + 2), &a[2]);
    printf("%d = %d", *(a + 2), a[2]);
}

void mutiAssignment() {
    // 含6个数组元素的数组，每个数组元素内含12个int类型的元素
    int a[6][12]  = {
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
    };

    for (int i = 0; i <5; ++i) {
        printf("\n");
        for (int j = 0; j < 12; ++j) {
            printf("a[%d][%d]=%d  ", i, j, a[i][j]);
        }
    }

    printf("\n多维数组赋值1\n");
    int b[2][3] = {{1,2}, {2, 3}};
    for (int k = 0; k < 2; ++k) {
        for (int i = 0; i < 3; ++i) {
            printf("b[%d][%d]=%d  ", k, i, b[k][i]);
        }
    }

    printf("\n多维数组赋值2\n");
    int e[2][3] = {1,2, 2, 3};
    for (int k = 0; k < 2; ++k) {
        for (int i = 0; i < 3; ++i) {
            printf("e[%d][%d]=%d  ", k, i, e[k][i]);
        }
    }
}

void assignment() {
    int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    for (int i = 0; i < 8; ++i) {
        printf("%d ", a[i]);
    }
    printf("\n给下标为3的第四个元素赋值\n");
    a[3] = 78;
    for (int i = 0; i < 8; ++i) {
        printf("%d ", a[i]);
    }
}

void initArrayTemp() {
    // 含有 40 个char 类型的数据， 方括号中的数字表明数组中元素的个数
    char name[40];
    // 含有 8 个 int 类型的数据， 初始化了 8 个元素
    int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
    // 数组元素下标从0开始，a[0] 代表第一个元素
    printf("%d\n", a[1]);

    printf("初始化值小于数组个数：\n");
    // 初始化的元素少于数组个数，那么剩余的值存储的垃圾值，初始化为0
    int b[4] = {8};
    for (int i = 0; i < 4; ++i) {
        printf("%d ", b[i]);
    }
    printf("\n初始化值大于数组个数：\n");
    // 初始化的元素大于数组个数，去调用的话会直接报错
//    int c[4] = {8, 1, 2, 3, 4, 5, 6, 77};
//    for (int i = 0; i < 15; ++i) {
//        printf("%d ", c[i]);
//    }
    printf("\n不设定数组个数:\n");
    // 如果初始化数组时省略方括号中的数字，编译器会根据初始化列表中的项数来确定数组的大小
    int d[] = {1, 2, 3, 4, 5, 6, 9, 11, 23};
    // sizeof运算符给出它的运算对象的大小（以字节为单位）。所以sizeof(d)是整个数组的大小（以字节为单位），sizeof(d[0])是数组中一个元素的大小（以字节为单位）。整个数组的大小除以单个元素的大小就是数组元素的个数。
    for (int j = 0; j < sizeof(d) / sizeof(d[0]); ++j) {
        printf("%d ", d[j]);
    }

    printf("\n指定初始化某个元素:\n");
    // 在初始化列表中使用带方括号的下标指明待初始化的元素
    int e[15] = {1, 2, [3] = 9, [9] = 88, [14] = 3};
    for (int k = 0; k < 15; ++k) {
        printf("%d ", e[k]);
    }
}
